package com.zhiyou.app.config;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.zhiyou.app.common.constant.CommonConstant;
import com.zhiyou.app.common.starejob.StartJob;
import com.zhiyou.app.pojo.entity.OrderEntity;
import com.zhiyou.app.pojo.enums.OrderStatusEnum;
import com.zhiyou.app.service.IOrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * @author zhangqiang
 * 订单完成任务定时监听器
 */
@Slf4j
@Component
public class OrderCompleteListener implements StartJob {
    @Resource
    private IOrderService orderService;

    @Override
    public void run() throws Exception {
        Executors.newScheduledThreadPool(1, r -> {
            Thread thread = new Thread(r, "enhanced-expiring-map-scheduler");
            thread.setDaemon(true);
            return thread;
        }).scheduleWithFixedDelay(this::runTask, 24, 24, TimeUnit.HOURS);
    }

    @Transactional(rollbackFor = Exception.class)
    public void runTask() {
        CommonConstant.ORDER_MAP_4_COMPLETE.setExpiryListener((n, o) -> {
            orderService.completeOrder(o);
        });
        List<OrderEntity> closedOrder = new ArrayList<>();
        //每天执行订单完成状态校验，订单超过3天开始的，则关闭订单
        Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(() -> {
            orderService.list(new LambdaUpdateWrapper<OrderEntity>().in(OrderEntity::getOrderStatus,
                    Arrays.asList(OrderStatusEnum.FINISHED, OrderStatusEnum.CREATED, OrderStatusEnum.WAIT4PAY))).forEach(o -> {
                long offsetSecond = DateUtil.between(o.getUpdateTime(), new Date(), DateUnit.SECOND);
                //超过3天，需要确认收货
                if (offsetSecond > 24 * 60 * 60 * 3) {
                    if (o.getOrderStatus() == OrderStatusEnum.FINISHED) {
                        orderService.completeOrder(o);
                    } else if (OrderStatusEnum.WAIT4PAY == o.getOrderStatus() || OrderStatusEnum.CREATED == o.getOrderStatus()) {
                        o.setOrderStatus(OrderStatusEnum.CLOSED);
                        closedOrder.add(o);
                    }
                } else {
                    if (o.getOrderStatus() == OrderStatusEnum.FINISHED) {
                        CommonConstant.ORDER_MAP_4_COMPLETE.put(o.getOrderNum(), o, offsetSecond, TimeUnit.SECONDS);
                    }
                }
            });
            if (!closedOrder.isEmpty()) {
                orderService.updateBatchById(closedOrder);
                closedOrder.clear();
            }
        }, 5, 60 * 24, TimeUnit.MINUTES);
    }
}
